<template>
  <div class="dg-row dg-body-cell" :class="{'auto-height': rootConfig.autoHeight}" ref="cell" :style="cellStyle" @mouseover="onRowMouseOver(node)" @mouseout="onRowMouseOut(node)" @click="onRowClick(node)">
    <div class="dg-check" v-if="column.checkbox" @click.stop>
      <checkbox :disabled="node.checkDisabled" :value="node.checked" @input="onCheckStateChange"></checkbox>
    </div>
    <div class="dg-tree-cell-unit" v-if="rootConfig.isTree && column.expandable">
      <span :style="blankStyle"></span>
      <span v-if="node && node.hasChildren" :class="toggleClass" @click="onToggle"></span>
    </div>
    <template v-if="!column.cellTemplate">
      {{displayValue}}
    </template>
    <div ref="cellTemplate" v-if="column.cellTemplate">
    </div>
  </div>
</template>

<script>
  import _ from 'lodash'
  import Vue from 'vue'
  import Checkbox from '../components/Checkbox.vue'
  import elementResizeEvent from 'element-resize-event'
  export default {
    components: {Checkbox},
    props: {
      rootConfig: {
        type: Object,
        default () {
          return {}
        }
      },
      column: Object,
      node: Object
    },
    data () {
      return {
        selected: false,
        tInstance: null,
        height: 0
      }
    },
    computed: {
      toggleClass () {
        return this.node.expanded ? 'open' : 'closed'
      },
      blankStyle () {
        return {width: `${(this.rootConfig.blankUnitWidth || 12) * this.node.level}px`}
      },
      displayValue () {
        let val = this.node.data[this.column.field]
        if (this.column.cellRenderer && _.isFunction(this.column.cellRenderer)) {
          return this.column.cellRenderer(val, this.node, this.column)
        }
        return val
      },
      cellStyle () {
        return {
          'padding-left': `${this.column.checkbox ? '30px' : null}`
        }
      }
    },
    methods: {
      onToggle () {
        this.$emit('toggle', this.node)
      },
      onCheckStateChange (checked) {
        Vue.set(this.node, 'checked', checked)
        this.$emit('check', this.node)
        if (!this.rootConfig.selectionNotEqualsChecking) {
          Vue.set(this.node, 'selected', this.node.checked)
        }
      },
      onRowMouseOver () {
        this.$emit('mouseover', this.node)
      },
      onRowMouseOut () {
        this.$emit('mouseout', this.node)
      },
      onRowClick () {
        this.$emit('click', this.node)
      },
      initCell () {
        if (!this.node._cellCtxList) {
          this.node._cellCtxList = [this]
        } else {
          this.node._cellCtxList.push(this)
        }
        let self = this
        if (self.column.cellTemplate) {
          self.tInstance = new Vue({
            el: self.$refs.cellTemplate,
            methods: {
              setNode (node) {
                this.data = node
              },
              getNode () {
                return this.data
              }
            },
            beforeCreate () {
              this.$options.template = self.column.cellTemplate
              if (self.column.context) {
                let obj = {}
                _.forOwn(self.column.context, (v, k) => {
                  if (_.isFunction(v)) {
                    this.$options.methods[k] = v
                  } else {
                    obj[k] = v
                  }
                })
                this.$options.data = function () {
                  return {data: self.node, ...obj}
                }
              } else {
                this.$options.data = function () {
                  return {data: self.node}
                }
              }
            }
          })
        }
        if (self.rootConfig.autoHeight) {
          this.resizeHandler = _.debounce(() => {
            this.height = this.$refs.cell.offsetHeight
            this.$emit('resize', this)
          }, 200, {leading: false, maxWait: 300})
          elementResizeEvent(this.$refs.cell, this.resizeHandler)
          this.$nextTick(() => {
            this.resizeHandler()
          })
        }
      }
    },
    mounted () {
      this.initCell()
    },
    watch: {
      node () {
        this.tInstance && this.tInstance.setNode(this.node)
      }
    },
    beforeDestroy () {
      if (this.rootConfig.autoHeight) {
        this.resizeHandler && elementResizeEvent.unbind(this.$refs.cell, this.resizeHandler)
      }
      let idx = this.node._cellCtxList.indexOf(this)
      if (idx > -1) {
        this.node._cellCtxList.splice(idx, 1)
      }
    }
  }
</script>
